//
//  NSExceptionStackTrace.m
//  Barak
//
//  Created by Ofri Wolfus on 06/01/07.
//  Copyright 2007 Ofri Wolfus. All rights reserved.
//

#import <ExceptionHandling/NSExceptionHandler.h>
#import "NSExceptionStackTrace.h"


// Code taken from http://www.cocoadev.com/index.pl?StackTraces
// and modified by Ofri Wolfus.
static NSString *DPDecodeStackTrace(NSString *stackTrace) {
	NSMutableString *result = [NSMutableString string];
    NSString *str = [NSString stringWithFormat:@"/usr/bin/atos -p %d %@ | tail -n +3 | head -n +%d | c++filt | cat -n",
		[[NSProcessInfo processInfo] processIdentifier],
		stackTrace, ([[stackTrace componentsSeparatedByString:@"  "] count] - 4)];
	FILE *file = popen( [str UTF8String], "r" );
	
	if (file) {
        char buffer[512];
        size_t length;
        
        while ((length = fread( buffer, 1, sizeof(buffer), file ))) {
			NSString *s = [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:buffer
																			  length:length * sizeof(char)
																		freeWhenDone:NO]
												encoding:NSUTF8StringEncoding];
			[result appendString:s];
			[s release];
        }
        
        pclose(file);
    }
	
	return result;
}

@implementation NSException (DPStackTrace)

- (NSString *)decodedStackTrace {
	NSString *stackTrace = [[self userInfo] objectForKey:NSStackTraceKey];
	return stackTrace ? DPDecodeStackTrace(stackTrace) : nil;
}

@end
